
import React, { Component } from "react";
import { Card, Button, Table, Modal, Form, Input, Select, message } from "antd";
import { PlusOutlined, ExclamationCircleOutlined } from "@ant-design/icons";
import dayjs from "dayjs";
import { PAGE_SIZE } from "../../config";
import { reqUserAdd, reqUserDelete, reqUserList, reqUserUpdate, reqUserUpdatePassword } from "../../api";
const { Item } = Form;
const { Option } = Select;
const { confirm } = Modal;

export default class User extends Component {

    state = {
        columnsConfig: [
            {
                title: "用户名",
                dataIndex: "username",
                key: "username"
            },
            {
                title: "邮箱",
                dataIndex: "email",
                key: "email"
            },
            {
                title: "电话",
                dataIndex: "phone",
                key: "phone"
            },
            {
                title: "注册时间",
                dataIndex: "create_time",
                key: "create_time",
                render: time => dayjs(time).format("YYYY-MM-DD")
            },
            {
                title: "所属角色",
                key: "role_id",
                dataIndex: "role_id",
                render: (role_id) => {
                    return this.state.roleList.find(v => v._id === role_id).name;
                }
            },
            {
                align: "center",
                title: "操作",
                key: "caozuo",
                render: (item) => {
                    return (
                        <div>
                            <Button type="link" onClick={() => { this.onButtonClickModifyUser(item) }}>修改</Button>
                            <Button type="link" onClick={() => { this.onButtonClickDeleteUser(item) }}>删除</Button>
                            <Button type="link" onClick={() => { this.onButtonClickUpdateUserPassword(item) }}>重置密码</Button>
                        </div>
                    )
                }
            }
        ],
        //用户列表
        userList: [],
        //角色列表
        roleList: [],
        //增加用户弹框控制
        isShowAdd: false,
        //重置密码弹框控制
        isShowUpdatePassword: false,
        //新增或修改，add/update
        modalType: "",
        //当前选择用户的id
        currentId: "",
        //当前选择用户的创建时间
        currentCreateTime: "",
        //当前重置密码用户的id
        currentUpdatePasswordId: ""
    }

    formRef = React.createRef();
    formUpdatePasswordRef = React.createRef();

    /**
     * 新增用户按钮点击监听
     */
    onButtonClickAddUser = () => {
        this.setState({ isShowAdd: true, modalType: "add" });
    }

    /**
     * 修改用户按钮点击监听
     * @param {在列表中选择的用户item} item 
     */
    onButtonClickModifyUser = (item) => {
        let { _id, username, phone, email, create_time, password, role_id } = item;
        //一定要在弹框打开了之后再获取form，否则form的current为undefined
        this.setState({ isShowAdd: true, modalType: "update", currentId: _id, currentCreateTime: create_time }, () => {
            this.formRef.current.setFieldsValue({ username, phone, email, password, role_id })
        });
    }

    /**
     * 删除用户
     * @param {要删除的用户} item 
     */
    onButtonClickDeleteUser = (item) => {
        let that = this;
        //用到modal中的confirm方法
        confirm(
            {
                title: '删除用户',
                icon: <ExclamationCircleOutlined />,
                content: '是否确定删除用户?',
                okText: '是',
                okType: 'danger',
                cancelText: '否',
                async onOk() {
                    let result = await reqUserDelete(item._id);
                    if (result) {
                        message.success(result);
                        let newList = that.state.userList.filter(v => v._id !== item._id);
                        that.setState({ userList: newList });
                    }
                },
                onCancel() {
                    //取消啥也不干
                },
            }
        );
    }

    /**
     * 重置密码按钮监听，弹出重置密码弹框
     * @param {要修改密码的用户对象} item 
     */
    onButtonClickUpdateUserPassword = (item) => {
        this.setState({ currentUpdatePasswordId: item._id, isShowUpdatePassword: true });
    }

    /**
     * 重置密码弹框的确认监听，提交form表单
     */
    onButtonUpdatePasswordConfirmClick = () => {
        this.formUpdatePasswordRef.current.submit();
    }

    /**
     * 重置密码弹框的取消监听，重置form表单
     */
    onButtonUpdatePasswordCancelClick = () => {
        this.setState({ currentUpdatePasswordId: "", isShowUpdatePassword: false });
        this.formUpdatePasswordRef.current.resetFields();
    }

    /**
     * 重置密码的from表单通过rules后的回调
     * 发送重置密码的请求
     */
    onUpdatePasswordFinish = async () => {
        let { password, password1 } = this.formUpdatePasswordRef.current.getFieldsValue();
        if (password === password1) {
            let result = await reqUserUpdatePassword(this.state.currentUpdatePasswordId, password);
            if (result) {
                message.success("修改密码成功")
                this.setState({ currentUpdatePasswordId: "", isShowUpdatePassword: false });
                this.formUpdatePasswordRef.current.resetFields();
            }
        } else {
            message.error("两次密码输入不一致，请重新输入")
        }
    }

    /**
     * 新增或修改用户资料的弹框确认监听
     * 提交form表单
     */
    onButtonAddConfirmClick = () => {
        this.formRef.current.submit();
    }

    /**
     * 新增或修改用户资料的弹框确认监听
     * 重置form表单
     */
    onButtonAddCancelClick = () => {
        this.setState({ isShowAdd: false, modalType: "", currentId: "", currentCreateTime: "" });
        this.formRef.current.resetFields();
    }

    /**
     * 新增或修改用户的from表单通过rules后的回调
     * 根据modaltype来判断是新增还是更新，并发送对应的请求
     */
    onFinish = async () => {
        let result
        let newUserList
        if (this.state.modalType === "add") {
            result = await reqUserAdd(this.formRef.current.getFieldsValue());
            result["create_time"] = Date.now();
            newUserList = [...this.state.userList];
        } else {
            let { username, phone, email, role_id } = this.formRef.current.getFieldsValue();
            let _id = this.state.currentId;
            let create_time = this.state.currentCreateTime;
            result = await reqUserUpdate({ _id, username, create_time, phone, email, role_id });
            newUserList = this.state.userList.filter(v => v._id !== _id);
        }
        newUserList.unshift(result);
        this.setState({ isShowAdd: false, modalType: "", userList: newUserList, currentId: "", currentCreateTime: "" });
        this.formRef.current.resetFields();
    }

    /**
     * 新增或修改用户的from表单未通过rules后的回调
     */
    onFinishFailed = () => {
        //本地form没通过规则回调，啥也不做
    }

    /**
     * 获取用户列表
     */
    getUserList = async () => {
        let result = await reqUserList();
        this.setState({ userList: result.users.reverse(), roleList: result.roles });
    }

    componentDidMount() {
        this.getUserList();
    }

    render() {
        return (
            <div>
                <Card
                    title={
                        <Button
                            icon={<PlusOutlined />}
                            type="primary"
                            onClick={this.onButtonClickAddUser}
                        >
                            创建用户
                        </Button>
                    }
                >
                    <Table
                        dataSource={this.state.userList}
                        rowKey="_id"
                        columns={this.state.columnsConfig}
                        bordered
                        pagination={
                            {
                                pageSize: PAGE_SIZE,
                                showQuickJumper: true
                            }
                        }
                    />
                </Card>
                <Modal
                    title={(this.state.modalType === "add") ? "新增用户" : "修改用户"}
                    visible={this.state.isShowAdd}
                    okText="确定"
                    cancelText="取消"
                    onOk={this.onButtonAddConfirmClick}
                    onCancel={this.onButtonAddCancelClick}
                >
                    <Form
                        ref={this.formRef}
                        onFinish={this.onFinish}
                        onFinishFailed={this.onFinishFailed}
                        labelCol={{ span: 3 }}
                        wrapperCol={{ span: 20 }}
                    >
                        <Item
                            label="用户名"
                            name="username"
                            rules={[
                                {
                                    required: true,
                                    message: '请输入用户名，不能为空',
                                },
                                {
                                    pattern: /^[\w+$\u4e00-\u9fa5]/,
                                    message: "用户名是汉字、字母、数字、下划线组成"
                                }
                            ]}
                        >
                            <Input placeholder="请输入用户名" />
                        </Item>
                        <Item
                            label="密码"
                            name="password"
                            rules={(this.state.modalType === "add") ? [
                                {
                                    required: true,
                                    message: '请输入密码，不能为空',
                                },
                                {
                                    pattern: /^[\w+$\u4e00-\u9fa5]/,
                                    message: "用户名是汉字、字母、数字、下划线组成"
                                },
                                {
                                    min: 4,
                                    max: 12,
                                    message: "密码不能小于4位,不能大于12位"
                                }
                            ] : []}
                        >
                            <Input disabled={this.state.modalType === "update"} placeholder="请输入密码" type="password" />
                        </Item>
                        <Item
                            label="手机号"
                            name="phone"
                            rules={[
                                {
                                    required: true,
                                    validator: (_, v) => {
                                        if (v.length !== 11 || isNaN(v))
                                            return Promise.reject("请输入正确的手机号");
                                        return Promise.resolve();
                                    }
                                }
                            ]}
                        >
                            <Input placeholder="请输入手机号" />
                        </Item>
                        <Item
                            label="邮箱"
                            name="email"
                            rules={[
                                {
                                    required: true,
                                    message: '邮箱不能为空',
                                }
                            ]}
                        >
                            <Input placeholder="请输入邮箱" type="email" />
                        </Item>
                        <Item
                            label="角色"
                            name="role_id"
                            rules={[
                                {
                                    required: true,
                                    message: "请选择一个角色"
                                },
                                {
                                    validator: (_, v) => {
                                        if (v === "def") {
                                            return Promise.reject("请选择分类");
                                        } else {
                                            return Promise.resolve();
                                        }
                                    }
                                }
                            ]}
                        >
                            <Select defaultValue="def">
                                <Option value="def">请选择角色</Option>
                                {
                                    this.state.roleList.map(v => {
                                        return <Option key={v._id} value={v._id}>{v.name}</Option>
                                    })
                                }
                            </Select>
                        </Item>
                    </Form>
                </Modal>
                <Modal
                    title="重置密码"
                    visible={this.state.isShowUpdatePassword}
                    okText="确定"
                    cancelText="取消"
                    onOk={this.onButtonUpdatePasswordConfirmClick}
                    onCancel={this.onButtonUpdatePasswordCancelClick}
                >
                    <Form
                        ref={this.formUpdatePasswordRef}
                        onFinish={this.onUpdatePasswordFinish}
                    >
                        <Item
                            label="输入密码"
                            name="password"
                            rules={[
                                {
                                    required: true,
                                    message: '请输入密码，不能为空',
                                },
                                {
                                    pattern: /^[\w+$\u4e00-\u9fa5]/,
                                    message: "用户名是汉字、字母、数字、下划线组成"
                                },
                                {
                                    min: 4,
                                    max: 12,
                                    message: "密码不能小于4位,不能大于12位"
                                }
                            ]}
                        >
                            <Input placeholder="请输入密码" type="password" />
                        </Item>
                        <Item
                            label="确认密码"
                            name="password1"
                            rules={[
                                {
                                    required: true,
                                    message: '请输入密码，不能为空',
                                },
                                {
                                    pattern: /^[\w+$\u4e00-\u9fa5]/,
                                    message: "用户名是汉字、字母、数字、下划线组成"
                                },
                                {
                                    min: 4,
                                    max: 12,
                                    message: "密码不能小于4位,不能大于12位"
                                }
                            ]}
                        >
                            <Input placeholder="确认密码" type="password" />
                        </Item>
                    </Form>
                </Modal>
            </div>
        )
    }
}